/**
 * COPYRIGHT. Harry Wu 2011. ALL RIGHTS RESERVED.
 * Project: just-ice
 * Author: Harry Wu <harrywu304@gmail.com>
 * Created On: Jul 1, 2011 2:56:23 PM
 *
*/ 
package org.justframework.ext.ice;

import org.justframework.core.ClientConnector;
import org.justframework.core.Request;
import org.justframework.core.Response;
import org.justframework.ext.ice.zeroc.ZerocRpcPrx;
import org.justframework.ext.ice.zeroc.ZerocRpcPrxHelper;
import org.justframework.util.JsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import Ice.Communicator;
import Ice.InitializationData;
import Ice.ObjectPrx;
import Ice.ObjectPrxHelperBase;
import Ice.Properties;
import Ice.Util;

/**
 * ice client connector
 *
 */
public class IceClient implements ClientConnector {
	
	/**
	 * logger
	 */
	private static Logger logger = LoggerFactory.getLogger(IceClient.class);
	
	private static Communicator ic = null;
	
	static {
		//初始化Ice Communicator
		Properties prop = Util.createProperties();
		prop.setProperty("Ice.MessageSizeMax", "1024");
		prop.setProperty("Ice.ThreadPool.Client.Size", "10");
		prop.setProperty("Ice.ThreadPool.Client.SizeMax", "200");
		prop.setProperty("Ice.ThreadPool.Client.SizeWarn", "200");
		//连接超时时间，单位为毫秒，默认为1秒
		prop.setProperty("Ice.Override.ConnectTimeout", "1000");
		//连接的生命周期，单位为秒，默认为60秒
		prop.setProperty("Ice.ACM.Client", "60");
		prop.setProperty("Ice.TCP.RcvSize", "65535");
		prop.setProperty("Ice.TCP.SndSize", "65535");
		InitializationData initData = new InitializationData();
		initData.properties = prop;
		ic = Ice.Util.initialize(initData);	
	}
	
	/**
	 * get ice proxy 
	 * @param host
	 * @param port
	 * @return
	 */
	private ObjectPrx getNativeProxy(String host, int port){
		String endpoint = ":tcp -h "+ host + " -p " + port + " -t 5000";
		String servantId = "ZerocRpc";
		logger.debug("endpoint:{}, servantId:{}", endpoint, servantId);
		ObjectPrx target = ic.stringToProxy(servantId + endpoint);	
		return target;
	}
	
	/**
	 * get ice proxy specified operation timeout
	 * @param host
	 * @param port
	 * @param operateTimeout
	 * @return
	 */
	private ObjectPrx getNativeProxy(String host, int port, long operateTimeout){
		ObjectPrxHelperBase helper = (ObjectPrxHelperBase)getNativeProxy(host,port);
		return helper.ice_timeout((int)operateTimeout);
	}

	/* (non-Javadoc)
	 * @see org.justframework.core.ClientConnector#rpc(org.justframework.core.Request)
	 */
	public Response rpc(Request request) {
		ObjectPrx target = null;
		if(request.getOperateTimeout() == 0){
			target = getNativeProxy(request.getUri().getHost(), request.getUri().getPort());
		} else {
			target = getNativeProxy(request.getUri().getHost(), request.getUri().getPort(), request.getOperateTimeout());
		}
		ZerocRpcPrx proxy = ZerocRpcPrxHelper.checkedCast(target);
		String requestJson = JsonUtil.toJson(request);
		logger.info("request:{}",requestJson);
		String rtn = proxy.rpc(requestJson);
		Response response = JsonUtil.toBean(rtn, Response.class);
		response.setReturnTimestamp(System.currentTimeMillis());
		logger.info("response:{}",response);
		return response;
	}

}
